#include "vtor_i2c.h"

// 加入用户工程宏
#ifdef __VTOR_LCEDA_OSC__
#include "main.h"

// 与at24c02保持一致吧，这个模块就相当于离线的at24c02
// 1 0 1 0 a2 a1 a0 rw，地址为0x50，写端口为0xa0，写端口为0xa1
// #define CROSS_I2C_DEV_ADDR			(0x50 << 1)
VtorI2c vtorI2cSlaveArray[4] = {
	{0x50 << 1},
	{0x51 << 1},
	{0x52 << 1},
	{0x53 << 1},
};
VtorI2c* demoRegI2c1 = NULL;
VtorI2c* demoBufI2cSlave1 = &vtorI2cSlaveArray[0];
VtorI2c* demoBufI2cSlave2 = NULL;
VtorI2c* demoBufI2cSlave3 = NULL;

typedef struct
{
	VtorI2c* i2c;
	GPIO_TypeDef* sclPort;
	uint16_t sclPin;
	GPIO_TypeDef* sdaPort;
	uint16_t sdaPin;
}VtorI2cSlave_Stm32HalArray;

const static VtorI2cSlave_Stm32HalArray VtorI2cSlaveGpioArray[] = 
{
	//GPIOB, GPIO_PIN_6, GPIOB, GPIO_PIN_7, // demo i2c slave
	{&vtorI2cSlaveArray[0], GPIOB, GPIO_PIN_8, GPIOB, GPIO_PIN_9}, // log i2c slave
	//GPIOB, GPIO_PIN_6, GPIOB, GPIO_PIN_7, // log i2c slave
	//GPIOB, GPIO_PIN_4, GPIOB, GPIO_PIN_5, // log i2c slave
	
	{NULL, NULL, 0, NULL, 0},
};

int8_t VtorI2cSlave_FindI2cIndex(VtorI2c* i2c)
{
	for(int8_t i = 0; VtorI2cSlaveGpioArray[i].i2c != NULL; i++)
	{
		if(i2c == VtorI2cSlaveGpioArray[i].i2c)
		{
			return i;
		}
	}
	return -1;
}


// 保留
void VtorI2cSlave_WriteScl(VtorI2c* i2c)
{
}

uint8_t VtorI2cSlave_ReadScl(VtorI2c* i2c)
{
	int8_t i = VtorI2cSlave_FindI2cIndex(i2c);
	if(i >= 0)
	{
		return HAL_GPIO_ReadPin(VtorI2cSlaveGpioArray[i].sclPort, VtorI2cSlaveGpioArray[i].sclPin);
	}
	return 0;
}

void VtorI2cSlave_WriteSda(VtorI2c* i2c, uint8_t level)
{
	int8_t i = VtorI2cSlave_FindI2cIndex(i2c);
	if(i >= 0)
	{
		HAL_GPIO_WritePin(VtorI2cSlaveGpioArray[i].sdaPort, VtorI2cSlaveGpioArray[i].sdaPin, (GPIO_PinState)level);
		return ;
	}
}


uint8_t VtorI2cSlave_ReadSda(VtorI2c* i2c)
{
	int8_t i = VtorI2cSlave_FindI2cIndex(i2c);
	if(i >= 0)
	{
		return HAL_GPIO_ReadPin(VtorI2cSlaveGpioArray[i].sdaPort, VtorI2cSlaveGpioArray[i].sdaPin);
	}
	return 0;
}

void VtorI2cSlave_SetSdaDir(VtorI2c* i2c, uint8_t dir)
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};
	// 输出模式时，设置为开漏输出
	// 输入模式时，设置成边沿中断输入
	switch(dir)
	{
	case GPIO_DIR_OUTPUT:
		GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
		break;
	case GPIO_DIR_IT_2EDGE:
		GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
		break;
	default:
		GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	}
	GPIO_InitStruct.Pull = GPIO_PULLUP;
	GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
	
	
	// 根据不同实例进行细分配置
	int8_t i = VtorI2cSlave_FindI2cIndex(i2c);
	if(i >= 0)
	{
		GPIO_InitStruct.Pin = VtorI2cSlaveGpioArray[i].sdaPin;
		HAL_GPIO_Init(VtorI2cSlaveGpioArray[i].sdaPort, &GPIO_InitStruct);
	}
}


void VtorI2cSlave_Init()
{
	GPIO_InitTypeDef GPIO_InitStruct = {0};

	GPIO_InitStruct.Pull = GPIO_PULLUP;
	// cubemx初始化引脚时，需配置成input，因为slaveI2c指针还未初始化
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
	// 如果是在VtorI2cSlave_Init函数内，将其初始化为上升沿和下降沿中断
	GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;

		
	// 根据不同实例进行细分配置
	for(int8_t i = 0; VtorI2cSlaveGpioArray[i].sclPort != 0; i++)
	{
		GPIO_InitStruct.Pin = VtorI2cSlaveGpioArray[i].sclPin;
		HAL_GPIO_Init(VtorI2cSlaveGpioArray[i].sclPort, &GPIO_InitStruct);
		GPIO_InitStruct.Pin = VtorI2cSlaveGpioArray[i].sdaPin;
		HAL_GPIO_Init(VtorI2cSlaveGpioArray[i].sdaPort, &GPIO_InitStruct);
	}
	
	
	GPIO_InitStruct.Mode = GPIO_MODE_INPUT; // 暂时只使用1个从机
	GPIO_InitStruct.Pin = GPIO_PIN_6 | GPIO_PIN_7;
	HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);

	/*
	VtorI2c* i2c = &vtorI2cSlaveArray[0];
	i2c->selfDevAddr = 0x7a;
	for(int i = 0; i < 10; i++)
	{
		//slaveI2c->regData[i] = 0xff;
		i2c->regData[i] = i % 10 + '0';
	}
	// 测试从机
    VtorI2cSlave_SetSdaDir(i2c, GPIO_DIR_IT_2EDGE);
	*/
	
	// 内部变量初始化完成后，再对指针进行赋值
	
	
	//demoBufI2cSlave1 = &vtorI2cSlaveArray[0];
	//demoBufI2cSlave1->selfDevAddr = (0x50 << 1); // 从机i2c地址（包括读写bit）
	
	//demoBufI2cSlave2 = &vtorI2cSlaveArray[1];
	//demoBufI2cSlave2->selfDevAddr = (0x51 << 1); // 从机i2c地址（包括读写bit）
	
	//demoBufI2cSlave3 = &vtorI2cSlaveArray[2];
	//demoBufI2cSlave3->selfDevAddr = (0x52 << 1); // 从机i2c地址（包括读写bit）
	
	
	
	// 最后 开启部中断
	HAL_NVIC_SetPriority(EXTI9_5_IRQn, 0, 0);
	HAL_NVIC_EnableIRQ(EXTI9_5_IRQn);
	//HAL_NVIC_SetPriority(EXTI15_10_IRQn, 0, 0);
	//HAL_NVIC_EnableIRQ(EXTI15_10_IRQn);
}

void VtorI2cSlave_StopCallback(VtorI2c* i2c)
{
	// VtorTimer_Create(VtorSlaveI2cTask, 0);
	// osMutexRelease(i2cMutex);
}

void VtorI2cSlave_WriteRegCallback(VtorI2c* i2c)
{
	// 主机写了接收寄存器，那么从机启动接收任务
	if(i2c->regAddr == VTOR_I2C_REG_SLAVE_RX_LEN)
	{
		//VtorTimer_Create(VtorTimer_BufferI2cSlaveRxTask, 0);
	}
}

void VtorI2cSlave_ReadRegCallback(VtorI2c* i2c)
{
	
}

// 在对应的中断处理函数内，写好正确的中断
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
	for(int8_t i = 0; VtorI2cSlaveGpioArray[i].sclPort != 0; i++)
	{
		if (GPIO_Pin == VtorI2cSlaveGpioArray[i].sclPin)
		{
			VtorI2cSlave_SclHandler(VtorI2cSlaveGpioArray[i].i2c);
			break;
		}
		if (GPIO_Pin == VtorI2cSlaveGpioArray[i].sdaPin)
		{
			VtorI2cSlave_SdaHandler(VtorI2cSlaveGpioArray[i].i2c);
			break;
		}
	}
}


#endif

